package com.softaria.windows.logic;

import java.util.HashMap;

import com.softaria.windows.model.View;
import com.softaria.windows.model.ViewUrl;
import com.softaria.windows.view.CloseConfirmation;
import com.softaria.windows.view.ViewCloseListener;
import com.softaria.windows.view.ViewCloseListenerRegistrator;

/**
 * Holds all {@link ViewCloseListener}s in static HashMap and knows for what
 * {@link View} closing they are listen
 * 
 * @author Roman M Kuzmin (roman@softaria.com)
 * 
 */
class ViewCloseListenerRegistratorImpl implements ViewCloseListenerRegistrator {

  private ViewCloseListener listener;

  private static HashMap<ViewUrl, ViewCloseListenerRegistratorImpl> registrators = new HashMap<ViewUrl, ViewCloseListenerRegistratorImpl>();

  /**
   * Adds itself to static map of registrators
   * 
   * @param view
   *          - listen to close of this view
   */
  public ViewCloseListenerRegistratorImpl(ViewUrl view) {
    registrators.put(view, this);
  }

  /**
   * Allows setting ViewCloseListener
   * 
   * @param listener
   */
  public void setViewCloseListener(ViewCloseListener listener) {
    this.listener = listener;

  }

  /**
   * Called by {@link ViewManager} when view got closed Calls corresponding
   * listeners
   * 
   * @param view
   */
  static void notifyViewClosed(ViewUrl view) {
    ViewCloseListenerRegistratorImpl registrator = registrators.get(view);

    if (registrator != null) {

      registrator.notifyViewClosed();

      // forget this view. It is already closed!
      registrators.remove(view);
    }
  }

  private void notifyViewClosed() {
    if (listener != null)
      listener.onClose();
    // Ensure they will not be called twice (closing can only happen once)
    listener = null;
  }

  /**
   * Called by {@link ViewManager} when closing procedure got started Asks
   * listener if View can be closed
   * 
   * @param url
   * @param closeConfirmation
   *          - it's method confirmClose() must be called when closing is
   *          allowed
   */
  static void tryClose(ViewUrl url, CloseConfirmation closeConfirmation) {
    ViewCloseListenerRegistratorImpl registrator = registrators.get(url);

    if (registrator == null) {
      // no close listener at all!
      closeConfirmation.confirmClose();
    } else {
      registrator.tryClose(closeConfirmation);
    }
  }

  private void tryClose(CloseConfirmation closeExecutor) {
    if (listener != null) {
      listener.beforeClose(closeExecutor);
    } else {
      closeExecutor.confirmClose();
    }
  }

}
